home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / sun4.md / machIntr.s < prev    next >
Text File  |  1991-07-23  |  6KB  |  197 lines

  1. /*
  2.  * machIntr.s --
  3.  *
  4.  *    Interrupts for sun4.
  5.  *
  6.  * Copyright 1989 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. .seg    "data"
  17. .asciz    "$Header: /sprite/src/kernel/mach/sun4.md/RCS/machIntr.s,v 9.3 91/07/23 12:42:52 mendel Exp $ SPRITE (Berkeley)"
  18. .align    8
  19. .seg    "text"
  20.  
  21. #include "machConst.h"
  22. #include "machAsmDefs.h"
  23. #include "vmSunConst.h"
  24. #include "devAddrs.h"
  25.  
  26. .align    8
  27. .seg    "text"
  28.  
  29. /*
  30.  * ----------------------------------------------------------------------
  31.  *
  32.  * MachHandleInterrupt --
  33.  *
  34.  *    Handle an interrupt by calling the specific interrupt handler whose
  35.  *    address is given as our first (and only) argument.
  36.  *
  37.  *    MachHandleInterrupt(SpecificInterruptHandlerAddress)
  38.  *
  39.  * Results:
  40.  *    None.
  41.  *
  42.  * Side effects:
  43.  *    None.
  44.  *
  45.  * ----------------------------------------------------------------------
  46.  */
  47. .globl    MachHandleInterrupt
  48. MachHandleInterrupt:
  49.     /* set us at interrupt level - do this in trap handler?? */
  50.     set    _mach_AtInterruptLevel, %VOL_TEMP1
  51.     ld    [%VOL_TEMP1], %SAFE_TEMP
  52.     set    1, %VOL_TEMP2
  53.     st    %VOL_TEMP2, [%VOL_TEMP1]
  54.  
  55.     and    %CUR_PSR_REG, MACH_PS_BIT, %VOL_TEMP1
  56.     set    _mach_KernelMode, %VOL_TEMP2
  57.     st    %VOL_TEMP1, [%VOL_TEMP2]    /* 0 = user, !0 = kernel */
  58.  
  59.     /* Call into vector table using tbr */
  60.     and    %CUR_TBR_REG, MACH_TRAP_TYPE_MASK, %o0
  61.     sub    %o0, MACH_LEVEL0_INT, %o0    /* get interrupt level */
  62.     srl    %o0, 2, %VOL_TEMP1        /* convert to index */
  63.     set    _machInterruptArgs, %VOL_TEMP2
  64.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP2
  65.     ld    [%VOL_TEMP2], %o0        /* arg, if any */
  66.     /*
  67.      * For now, this is the only way to get the interrupt pc to the
  68.      * profiler via the Timer_TimerService callback.  It's an implicit
  69.      * parameter.
  70.      */
  71.     mov    %CUR_PC_REG, %o1    /* pc as next arg. */
  72.     set    _machVectorTable, %VOL_TEMP2
  73.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP1
  74.     ld    [%VOL_TEMP1], %VOL_TEMP1
  75.     call    %VOL_TEMP1
  76.     nop
  77.  
  78.     set    _mach_AtInterruptLevel, %VOL_TEMP1
  79. #ifdef NOTDEF
  80.     tst    %SAFE_TEMP
  81.     bne    LeaveInterruptLevel
  82. #endif NOTDEF
  83.     nop
  84.     st    %g0, [%VOL_TEMP1]
  85. LeaveInterruptLevel:
  86.     /*
  87.      * Put a good return value into the return value register so that
  88.      * MachReturnFromTrap will be happy if we're returning to user mode.
  89.      */
  90.     mov    MACH_OK, %RETURN_VAL_REG
  91.  
  92.     set    _MachReturnFromTrap, %VOL_TEMP1
  93.     jmp    %VOL_TEMP1
  94.     nop
  95.  
  96.  
  97.  
  98. /*
  99.  * ----------------------------------------------------------------------
  100.  *
  101.  * MachVectoredInterrupt --
  102.  *
  103.  *    Handle an interrupt that requires getting an interrupt vector in
  104.  *    an interrupt acknowledge cycle.  The single argument to the routine is
  105.  *    the vme trap vector address to read.
  106.  *
  107.  * Results:
  108.  *    None.
  109.  *
  110.  * Side effects:
  111.  *    Handle the interrupt.
  112.  *
  113.  * ----------------------------------------------------------------------
  114.  */
  115. .globl    _MachVectoredInterrupt
  116. _MachVectoredInterrupt:
  117.     /* We need to return to a leaf routine, so we need to save a frame */
  118.     save    %sp, -MACH_FULL_STACK_FRAME, %sp
  119. .globl    _MachVectoredInterruptLoad
  120. _MachVectoredInterruptLoad:
  121.     lduba    [%i0] VMMACH_CONTROL_SPACE, %VOL_TEMP1    /* got vector */
  122.     sll    %VOL_TEMP1, 2, %VOL_TEMP1        /* convert to index */
  123.     set    _machInterruptArgs, %VOL_TEMP2
  124.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP2
  125.     ld    [%VOL_TEMP2], %o0            /* clientData arg */
  126.     set    _machVectorTable, %VOL_TEMP2
  127.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP2
  128.     ld    [%VOL_TEMP2], %VOL_TEMP2
  129.     call    %VOL_TEMP2                /* %o0 is arg */
  130.     nop
  131.     ret
  132.     restore
  133.  
  134.  
  135.  
  136. /*
  137.  * ----------------------------------------------------------------------
  138.  *
  139.  * MachHandleLevel15Intr --
  140.  *
  141.  *    Handle a level 15 interrrupt.  This is a non-maskable memory error
  142.  *    interrupt, and we want to clear the condition so we report only
  143.  *    the first CE.  Then we'll jump to MachTrap and go into the debugger.
  144.  *
  145.  * Results:
  146.  *    None.
  147.  *
  148.  * Side effects:
  149.  *    We should go into the debugger.
  150.  *
  151.  * ----------------------------------------------------------------------
  152.  */
  153. .globl    MachHandleLevel15Intr
  154. MachHandleLevel15Intr:
  155.     /*
  156.      * Put the register values into global registers so we can see
  157.      * what they were easily when entering the debugger, since we'll
  158.      * mess up the locals before we get there.  We won't survive this
  159.      * error anyway, so we won't be needing the globals again.
  160.      */
  161. #ifdef sun4c
  162.     set    VMMACH_ASYNC_ERROR_REG, %VOL_TEMP1
  163.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g5
  164.  
  165.     set    VMMACH_ASYNC_ERROR_ADDR_REG, %VOL_TEMP1
  166.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g6
  167.  
  168.     /* I must clear these too to clear async error.  Very silly. */
  169.     set    VMMACH_SYNC_ERROR_REG, %VOL_TEMP1
  170.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g0
  171.  
  172.     set    VMMACH_SYNC_ERROR_ADDR_REG, %VOL_TEMP1
  173.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g0
  174.  
  175.     /*
  176.      * To clear the interrupt condition, first write a 0 to the enable
  177.      * all interrupts bit, and then write a one again.
  178.      */
  179.     set    DEV_INTERRUPT_REG_ADDR, %VOL_TEMP1
  180.     ld    [%VOL_TEMP1], %VOL_TEMP2
  181.     andn    %VOL_TEMP2, MACH_ENABLE_ALL_INTERRUPTS, %VOL_TEMP2
  182.     st    %VOL_TEMP2, [%VOL_TEMP1]
  183.     or    %VOL_TEMP2, MACH_ENABLE_ALL_INTERRUPTS, %VOL_TEMP2
  184.     st    %VOL_TEMP2, [%VOL_TEMP1]
  185. #else
  186.     set    VMMACH_ADDR_CONTROL_REG, %VOL_TEMP1
  187.     ld    [%VOL_TEMP1], %g5
  188.  
  189.     and    %VOL_TEMP2, ~VMMACH_ENABLE_MEM_ERROR_BIT, %VOL_TEMP2
  190.     st    %VOL_TEMP2, [%VOL_TEMP1]
  191.     set    VMMACH_ADDR_ERROR_REG, %VOL_TEMP1
  192.     ld    [%VOL_TEMP1], %g6
  193. #endif
  194.     set    _MachTrap, %VOL_TEMP1
  195.     jmp    %VOL_TEMP1
  196.     nop
  197.